/*
 *  Carreaux.cpp
 *  Ray Tracing
 *
 *  Created by Jean-Marc Comby + Romain Desquesne on Tue Jun 08 2004.
 *  Copyright (c) 2004. All rights reserved.
 *
 */

#include "Carreaux.hpp"

#include "Formes/LibForm.hpp"

#include <stdlib.h>
#include <cmath>

using namespace std;

/**
 * Constructeur standard, qui initialise les champs de la classe mère
 * et ceux propres à la classe.
 *
 * La version par défaut crée un damier noir et blanc avec une Largeur
 * de 1.
 *
 * @param refl coefficient de réflexion.
 * @param trans coefficiente de transparence.
 * @param indice indice de réfraction.
 * @param reg coefficient de diffusion.
 * @param n1 première Couleur à utiliser pour le damier.
 * @param n2 deuxième Couleur à utiliser pour le damier.
 * @param larg largeur du damier.
 */
Carreaux::Carreaux(const double& refl, const double& trans,
		   const double& indice, const double& reg,
		   const Couleur& n1, const Couleur& n2, const double& larg)
  : Materiau( refl, trans, indice, reg ), Largeur( larg ) ,
    Color1( n1 ), Color2( n2 ), Volume( 0 )
{
  Type = tCarreaux;
}

/**
 * Constructeur standard, qui initialise les champs de la classe mère
 * et ceux propres à la classe. Ici on a en plus une déformation sur
 * la normale à la surface.
 *
 * @param refl coefficient de réflexion.
 * @param trans coefficiente de transparence.
 * @param indice indice de réfraction.
 * @param reg coefficient de diffusion.
 * @param bruit intensité de la perturbation sur la normale.
 * @param n1 première Couleur à utiliser pour le damier.
 * @param n2 deuxième Couleur à utiliser pour le damier.
 * @param larg largeur du damier.
 */
Carreaux::Carreaux(const double& refl, const double& trans,
		   const double& indice, const double& reg, const double& bruit,
		   const Couleur& n1, const Couleur& n2, const double& larg)
  : Materiau( refl, trans, indice, reg, bruit ), Largeur( larg ),
    Color1( n1 ), Color2( n2 ), Volume( 0 )
{
  Type = tCarreaux;
}

/**
 * Le destructeur n'a rien de spécial à faire.
 */
Carreaux::~Carreaux()
{}

/**
 * Modifie la valeur du champ Color, conformément à la parité des
 * coordonnées intrinsèques du point de la surface considéré.
 *
 * @param a point de la surface que l'on veut colorier.
 * @return une référence constante sur Color.
 */
Couleur Carreaux::couleur(const Coord &a)
{
  Coord carte( Volume -> intrinsequeReduite( a, Largeur ) );

  int x( static_cast< int >( floor( carte.x() ) ) );
  int y( static_cast< int >( floor( carte.y() ) ) );

  bool xpair( ( abs( x ) % 2 ) == 0 ),
    ypair( ( abs( y ) % 2 ) == 0 );

  // if ( carte.x() < -1.e-7 )
  //   xpair = !xpair;
  // if ( carte.y() < -1.e-7 )
  //   ypair = !ypair;

  if ( ( xpair && ypair ) || ( !xpair && !ypair ) )
      return Color1;
    else
      return Color2;

  /*
  // on calcul la partie entiere
  int x( static_cast< int >( a.x() / Largeur ) );
  int y( static_cast< int >( a.y() / Largeur ) );
  int z( static_cast< int >( a.z() / Largeur ) );
	
  // on regarde la parite
  bool xpair, ypair, zpair;
	
  xpair = ( ( abs( x ) % 2 ) == 0);
  ypair = ( ( abs( y ) % 2 ) == 0);
  zpair = ( ( abs( z ) % 2 ) == 0);
  // si les coord sont négatives, on inverse la parité
  if ( a.x() < -1.e-7 )
    xpair = !xpair;
  if ( a.y() < -1.e-7 )
    ypair = !ypair;
  if ( a.z() < -1.e-7 )
    zpair = !zpair;
	
  if ( zpair )
    if ( ( xpair && ypair ) || ( !xpair && !ypair ) )
      return Color1;
    else
      return Color2;
  else
    if ( ( xpair && ypair ) || ( !xpair && !ypair ) )
      return Color1;
    else
      return Color2;
*/
}

/**
 * Permet de modifier la valeur de Volume, car il n'est pas connu à
 * l'initialisation.
 *
 * @param forme nouvelle valeur de Volume.
 */
void Carreaux::setVolume(Forme* forme)
{
  Volume = forme;
}
